interface SSEMessage {
  type: string
  data: unknown
}

export class SSEService {
  private eventSource: EventSource | null = null
  private clientId: string
  private messageHandlers: Set<(message: SSEMessage) => void> = new Set()
  private _isConnected = false
  private pingInterval: NodeJS.Timer | null = null
  private lastPingTime: number = 0
  private reconnectTimeout: NodeJS.Timeout | null = null
  private readonly PING_TIMEOUT = 70000 // 增加到70秒
  private _isReconnecting = false

  constructor(clientId: string) {
    this.clientId = clientId
    this._isConnected = false
    this.eventSource = null
    this.lastPingTime = Date.now()
  }

  public get isConnected(): boolean {
    return this._isConnected && Date.now() - this.lastPingTime < this.PING_TIMEOUT
  }

  private startPingMonitor() {
    if (this.pingInterval) {
      clearInterval(this.pingInterval)
    }

    this.pingInterval = setInterval(() => {
      if (this._isConnected && !this._isReconnecting) {
        const timeSinceLastPing = Date.now() - this.lastPingTime
        if (timeSinceLastPing > this.PING_TIMEOUT) {
          console.warn(`Ping timeout (${timeSinceLastPing}ms), reconnecting...`)
          this.reconnect()
        }
      }
    }, 10000) // 增加到10秒检查一次
  }

  private clearReconnectTimeout() {
    if (this.reconnectTimeout) {
      clearTimeout(this.reconnectTimeout)
      this.reconnectTimeout = null
    }
  }

  private reconnect() {
    if (this._isReconnecting) {
      console.log('Already reconnecting, skipping...')
      return
    }

    this._isReconnecting = true
    console.log('Attempting to reconnect...')
    this.disconnect()

    this.clearReconnectTimeout()
    this.reconnectTimeout = setTimeout(() => {
      this.connect()
      this._isReconnecting = false
    }, 2000) // 增加重连延迟到2秒
  }

  public connect(): void {
    // 清理现有连接和定时器
    this.disconnect()

    if (this._isReconnecting) {
      console.log('Connection attempt while reconnecting, skipping...')
      return
    }

    const url = `${import.meta.env.VITE_API_BASE_URL}/sse/subscribe?client_id=${this.clientId}`

    try {
      console.log('Establishing new SSE connection...')
      this.eventSource = new EventSource(url)

      this.eventSource.onmessage = (event: MessageEvent) => {
        try {
          const message = JSON.parse(event.data)
          console.log('Received SSE message:', message)
          this.messageHandlers.forEach((handler) => handler(message))
        } catch (error) {
          console.error('Error parsing SSE message:', error)
        }
      }

      // 处理ping事件
      this.eventSource.addEventListener('ping', (event: MessageEvent) => {
        this.lastPingTime = Date.now()
        console.debug('Received ping:', event.data)
      })

      this.eventSource.onerror = (error) => {
        console.error('SSE connection error:', error)
        this._isConnected = false
        if (!this._isReconnecting) {
          this.reconnect()
        }
      }

      this.eventSource.onopen = () => {
        console.log('SSE connection established')
        this._isConnected = true
        this.lastPingTime = Date.now()
        this.startPingMonitor()
      }
    } catch (error) {
      console.error('Failed to establish SSE connection:', error)
      this._isConnected = false
      if (!this._isReconnecting) {
        this.reconnect()
      }
    }
  }

  public disconnect(): void {
    console.log('SSEService: Disconnecting...')
    this.clearReconnectTimeout()

    if (this.pingInterval) {
      clearInterval(this.pingInterval)
      this.pingInterval = null
    }

    if (this.eventSource) {
      this.eventSource.close()
      this.eventSource = null
    }

    this._isConnected = false
  }

  public addMessageHandler(handler: (message: SSEMessage) => void): void {
    this.messageHandlers.add(handler)
  }

  public removeMessageHandler(handler: (message: SSEMessage) => void): void {
    this.messageHandlers.delete(handler)
  }
}
